/*
 * @Description: 
 * @Author: Jimmy
 * @Date: 2023-07-23 12:21:31
 * @LastEditTime: 2023-07-23 12:54:47
 * @LastEditors:  
 */
import fs from 'fs'
import path from 'path'
import { Context } from "koa";
import jwt from 'jsonwebtoken'
import UseService from '../service/user.service'
import { callbackData } from "../utils/data.handler";
import { access, sql } from "../logger";
import { config } from "../config/config.default";
import { redisGet, redisSet } from "../utils/redis.client";
import { getSessionKey } from "../utils/wx.mini";
import WXBizDataCrypt from '../utils/WXBizDataCrypt'
import roleService from '../service/role.service';
import menuService from '../service/menu.service';
import menuController from './menu.controller';

class UploadController {
    //注册接口
    async register(ctx: Context) {
        //获取数据
        const { username = '', password = '', is_admin = 0 } = ctx.request.body;
        // 操作数据库
        try {
            const res = await UseService.createUser({ username, password, is_admin });
            // 返回结果
            access.info('用户注册成功', { username })
            ctx.body = callbackData('0', '用户注册成功', {
                id: res.id,
                username: username
            })
        } catch (err) {
            sql.error('注册用户失败', err)
            console.error('注册用户失败', err)
            ctx.app.emit('error', callbackData('3', '注册用户失败'), ctx);
        }
    }
    //登录
    async login(ctx: Context) {
        //获取数据
        const { username = '', password = '' } = ctx.request.body;
        try {
            //从返回结果中剔除password，其他属性放入新的对象中
            const { password, ...resUser } = await UseService.getUserInfo({ username })
            // 返回结果
            let {is_admin} = resUser;
            if(!is_admin){
                sql.error('无登录权限', { username })
                console.error('无登录权限', { username })
                ctx.app.emit('error', callbackData('3', '无登录权限'), ctx);
                return false;
            }
            access.info('用户登录成功', { username })
            let token = jwt.sign(resUser, config.jwt.secret as string, { expiresIn: config.jwt.expired })
            // redisSet(`userId_${resUser.id}`,resUser)
            ctx.body = callbackData('0', '用户登录成功', {
                token,
                userInfo:resUser
            })
        } catch (err) {
            sql.error('用户登录失败', err)
            console.error('用户登录失败', err)
            ctx.app.emit('error', callbackData('3', '用户登录失败'), ctx);
        }
    }
    //小程序手机号授权登录
    async wxLogin(ctx: Context) {
        let { jsCode, iv, encryptedData } = ctx.request.body;
        try {
            //请求获取openid
            let keyData: any = await getSessionKey(jsCode)
            let { session_key, openid } = keyData;
            let pc = new WXBizDataCrypt(config.mini.appid, session_key)
            //此方法即为获取用户手机号的方法，是微信的官方js库
            let data = pc.decryptData(encryptedData, iv)
            data.sessionKey = session_key;
            data.openid = openid;
            ctx.body = callbackData('0', '授权登录成功', data)
        } catch (err) {
            access.error('授权失败', err)
            console.error('授权失败', err)
            ctx.app.emit('error', callbackData('1', '授权失败'), ctx);
        }
    }
    //修改密码
    async updatePassword(ctx: Context) {
        //获取数据
        let { id, username } = ctx.state.user;
        let { password } = ctx.request.body || {};
        //操作数据库
        let res = await UseService.updateById({ id, password });
        if (res) {
            sql.info('修改密码成功', { username })
            console.error('修改密码成功', { username })
            ctx.body = callbackData('0', '修改密码成功')
        } else {
            sql.error('修改密码失败')
            console.error('修改密码失败')
            ctx.app.emit('error', callbackData('3', '修改密码失败'), ctx);
        }
    }
    //上传文件
    upload = async (ctx: Context) => {
        const file = ctx.request.files?.file;
        if (file) {
            // @ts-ignore
            let { originalFilename, filepath, mimetype } = file;
            const types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
            // @ts-ignore
            if (!types.includes(mimetype)) {
                access.error('非法文件上传')
                console.error('非法文件上传')
                ctx.app.emit('error', callbackData('1', '非法文件上传'), ctx);
                return false;
            }
            // @ts-ignore
            const reader = fs.createReadStream(filepath);
            // @ts-ignore
            const ext = path.extname(originalFilename);
            const filePath = 'upload/' + this.randomStr(32) + ext;
            // @ts-ignore
            const writer = fs.createWriteStream(`statics/` + filePath);
            reader.pipe(writer)
            ctx.body = callbackData('0', '上传文件', { image: filePath })
        } else {
            access.error('请上传文件')
            console.error('请上传文件')
            ctx.app.emit('error', callbackData('1', '请上传文件'), ctx);
            return false;
        }
    }
    randomStr = (len: number): string => {
        const seeder = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        let randomStr = '';
        for (let i = 0; i < len; i++) {
            randomStr += seeder.charAt(Math.floor(Math.random() * seeder.length))
        }
        return randomStr
    }
    //获取用户路由权限
    async getPermission(ctx:Context){
        let {role_id,is_admin,username}  =ctx.state.user || {};
        if(!is_admin){
            sql.error('无登录权限', { username })
            console.error('无登录权限', { username })
            ctx.app.emit('error', callbackData('3', '无登录权限'), ctx);
            return false;
        }
        try{
            let res = await roleService.findInfo({name:'',code:'',id:role_id});
            let allRoutes:any = await menuController.queryList(ctx);
            if(res){
                let menuKeys = JSON.parse(res.permission)
                let menus = dealRoutePermission(allRoutes.list,menuKeys)
                sql.info('获取权限成功', { username })
                console.error('获取权限成功', { username })
                ctx.body = callbackData('0', '获取权限成功',menus)
            }else{
                sql.error('权限不存在', { username })
                console.error('权限不存在', { username })
                ctx.app.emit('error', callbackData('3', '权限不存在'), ctx);
                return false;
            }
        }catch(err){
            sql.error('获取权限失败')
            console.error('获取权限失败')
            ctx.app.emit('error', callbackData('3', '获取权限失败'), ctx);
        }
    }
}

const dealRoutePermission = (originalData:any[],hasKeys:string[])=>{
    if(originalData && originalData.length){
        for(let i=0;i<originalData.length;i++){
            let item = originalData[i];
            if(hasKeys.indexOf(item.path)==-1){
                originalData.splice(i,1)
                i--;
            }else{
                if(item.children){
                    item.children = dealRoutePermission(item.children,hasKeys)
                }
            }
        }
        return originalData;
    }
    return []
}

export default new UploadController